from flask import Blueprint, request
from flask_jwt_extended import jwt_required, get_jwt_identity
from app import db
from app.models import Certificate, ExamRecord
from app.utils.response import success_response, error_response, paginated_response
from app.utils.decorators import admin_required, user_required
from app.services.certificate_service import CertificateService
from loguru import logger

certificates_bp = Blueprint('certificates', __name__)

@certificates_bp.route('/', methods=['GET'])
@user_required
def get_certificates():
    """获取用户的证书列表"""
    try:
        current_user_id = get_jwt_identity()
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 10, type=int), 100)
        
        query = Certificate.query.filter_by(user_id=current_user_id, is_valid=True)
        
        pagination = query.order_by(Certificate.created_at.desc()).paginate(
            page=page,
            per_page=per_page,
            error_out=False
        )
        
        certificates = []
        for certificate in pagination.items:
            cert_dict = certificate.to_dict()
            # 添加考试信息
            cert_dict['exam'] = certificate.exam_record.exam.to_dict()
            certificates.append(cert_dict)
        
        return paginated_response(
            certificates,
            page,
            per_page,
            pagination.total
        )
        
    except Exception as e:
        logger.error(f"获取证书列表失败: {e}")
        return error_response('获取证书列表失败', 500)

@certificates_bp.route('/my', methods=['GET'])
@user_required
def get_my_certificates():
    """获取我的证书列表（小程序兼容接口）"""
    try:
        current_user_id = get_jwt_identity()
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 10, type=int), 100)
        
        query = Certificate.query.filter_by(user_id=current_user_id, is_valid=True)
        
        pagination = query.order_by(Certificate.created_at.desc()).paginate(
            page=page,
            per_page=per_page,
            error_out=False
        )
        
        certificates = []
        for certificate in pagination.items:
            cert_dict = certificate.to_dict()
            # 添加考试信息
            cert_dict['exam'] = certificate.exam_record.exam.to_dict()
            certificates.append(cert_dict)
        
        return paginated_response(
            certificates,
            page,
            per_page,
            pagination.total
        )
        
    except Exception as e:
        logger.error(f"获取我的证书列表失败: {e}")
        return error_response('获取证书列表失败', 500)

@certificates_bp.route('/stats', methods=['GET'])
@user_required
def get_certificate_stats():
    """获取证书统计信息"""
    try:
        current_user_id = get_jwt_identity()
        
        # 统计证书数量
        total_certificates = Certificate.query.filter_by(
            user_id=current_user_id, 
            is_valid=True
        ).count()
        
        # 统计不同类型的证书
        from app.models import Exam
        certificates = Certificate.query.filter_by(
            user_id=current_user_id, 
            is_valid=True
        ).all()
        
        exam_types = {}
        for cert in certificates:
            exam_title = cert.exam_record.exam.title
            if exam_title not in exam_types:
                exam_types[exam_title] = 0
            exam_types[exam_title] += 1
        
        # 最新获得的证书
        latest_certificate = Certificate.query.filter_by(
            user_id=current_user_id, 
            is_valid=True
        ).order_by(Certificate.created_at.desc()).first()
        
        stats = {
            'total_certificates': total_certificates,
            'exam_types': exam_types,
            'latest_certificate': {
                'id': latest_certificate.id,
                'title': latest_certificate.title,
                'exam_title': latest_certificate.exam_record.exam.title,
                'created_at': latest_certificate.created_at.isoformat()
            } if latest_certificate else None
        }
        
        return success_response(stats)
        
    except Exception as e:
        logger.error(f"获取证书统计失败: {e}")
        return error_response('获取证书统计失败', 500)

@certificates_bp.route('/<int:certificate_id>', methods=['GET'])
@user_required
def get_certificate(certificate_id):
    """获取证书详情"""
    try:
        current_user_id = get_jwt_identity()
        
        certificate = Certificate.query.filter_by(
            id=certificate_id,
            user_id=current_user_id,
            is_valid=True
        ).first()
        
        if not certificate:
            return error_response('证书不存在', 404)
        
        cert_dict = certificate.to_dict()
        cert_dict['exam'] = certificate.exam_record.exam.to_dict()
        
        return success_response(cert_dict)
        
    except Exception as e:
        logger.error(f"获取证书详情失败: {e}")
        return error_response('获取证书详情失败', 500)

@certificates_bp.route('/generate', methods=['POST'])
@user_required
def generate_certificate():
    """生成证书"""
    try:
        data = request.get_json()
        exam_record_id = data.get('exam_record_id')
        
        if not exam_record_id:
            return error_response('考试记录ID不能为空', 400)
        
        current_user_id = get_jwt_identity()
        
        # 检查考试记录
        exam_record = ExamRecord.query.filter_by(
            id=exam_record_id,
            user_id=current_user_id
        ).first()
        
        if not exam_record:
            return error_response('考试记录不存在', 404)
        
        if not exam_record.is_passed:
            return error_response('考试未通过，无法生成证书', 400)
        
        # 检查是否已有证书
        existing_certificate = Certificate.query.filter_by(
            exam_record_id=exam_record_id
        ).first()
        
        if existing_certificate:
            return error_response('证书已存在', 400)
        
        # 生成证书
        certificate_service = CertificateService()
        certificate = certificate_service.generate_certificate(exam_record)
        
        cert_dict = certificate.to_dict()
        cert_dict['exam'] = certificate.exam_record.exam.to_dict()
        
        return success_response(cert_dict, '证书生成成功')
        
    except Exception as e:
        logger.error(f"生成证书失败: {e}")
        return error_response('生成证书失败', 500)

@certificates_bp.route('/download/<int:certificate_id>', methods=['GET'])
@user_required
def download_certificate(certificate_id):
    """下载证书"""
    try:
        current_user_id = get_jwt_identity()
        
        certificate = Certificate.query.filter_by(
            id=certificate_id,
            user_id=current_user_id,
            is_valid=True
        ).first()
        
        if not certificate:
            return error_response('证书不存在', 404)
        
        # 生成证书图片
        certificate_service = CertificateService()
        image_url = certificate_service.generate_certificate_image(certificate)
        
        return success_response({
            'certificate_id': certificate.id,
            'image_url': image_url,
            'download_url': image_url
        })
        
    except Exception as e:
        logger.error(f"下载证书失败: {e}")
        return error_response('下载证书失败', 500)

@certificates_bp.route('/<int:certificate_id>/verify', methods=['GET'])
def verify_certificate(certificate_id):
    """验证证书真伪"""
    try:
        certificate = Certificate.query.filter_by(
            id=certificate_id,
            is_valid=True
        ).first()
        
        if not certificate:
            return success_response({
                'is_valid': False,
                'message': '证书不存在或已失效'
            })
        
        # 验证证书信息
        verification_info = {
            'is_valid': True,
            'certificate_id': certificate.id,
            'title': certificate.title,
            'user_nickname': certificate.user.nickname,
            'exam_title': certificate.exam_record.exam.title,
            'exam_score': certificate.exam_record.score,
            'pass_score': certificate.exam_record.exam.pass_score,
            'issue_date': certificate.created_at.isoformat(),
            'certificate_number': certificate.certificate_number
        }
        
        return success_response(verification_info)
        
    except Exception as e:
        logger.error(f"验证证书失败: {e}")
        return error_response('验证证书失败', 500)

# 管理员接口
@certificates_bp.route('/admin/', methods=['GET'])
@admin_required
def admin_get_certificates():
    """管理员获取证书列表"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 10, type=int), 100)
        user_id = request.args.get('user_id', type=int)
        is_valid = request.args.get('is_valid', type=lambda v: v.lower() == 'true')
        
        query = Certificate.query
        
        if user_id:
            query = query.filter_by(user_id=user_id)
        if is_valid is not None:
            query = query.filter_by(is_valid=is_valid)
        
        pagination = query.order_by(Certificate.created_at.desc()).paginate(
            page=page,
            per_page=per_page,
            error_out=False
        )
        
        certificates = []
        for certificate in pagination.items:
            cert_dict = certificate.to_dict()
            cert_dict['user'] = certificate.user.to_dict()
            cert_dict['exam'] = certificate.exam_record.exam.to_dict()
            certificates.append(cert_dict)
        
        return paginated_response(
            certificates,
            page,
            per_page,
            pagination.total
        )
        
    except Exception as e:
        logger.error(f"管理员获取证书列表失败: {e}")
        return error_response('获取证书列表失败', 500)

@certificates_bp.route('/admin/<int:certificate_id>', methods=['PUT'])
@admin_required
def admin_update_certificate(certificate_id):
    """管理员更新证书"""
    try:
        certificate = Certificate.query.get(certificate_id)
        if not certificate:
            return error_response('证书不存在', 404)
        
        data = request.get_json()
        title = data.get('title')
        content = data.get('content')
        is_valid = data.get('is_valid')
        
        if title is not None:
            certificate.title = title
        if content is not None:
            certificate.content = content
        if is_valid is not None:
            certificate.is_valid = is_valid
        
        db.session.commit()
        
        return success_response(certificate.to_dict(), '证书更新成功')
        
    except Exception as e:
        logger.error(f"更新证书失败: {e}")
        return error_response('更新证书失败', 500)

@certificates_bp.route('/admin/<int:certificate_id>', methods=['DELETE'])
@admin_required
def admin_delete_certificate(certificate_id):
    """管理员删除证书"""
    try:
        certificate = Certificate.query.get(certificate_id)
        if not certificate:
            return error_response('证书不存在', 404)
        
        certificate_no = certificate.certificate_no
        db.session.delete(certificate)
        db.session.commit()
        
        return success_response(None, '证书删除成功')
        
    except Exception as e:
        logger.error(f"删除证书失败: {e}")
        return error_response('删除证书失败', 500) 

